/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package cn.newtest.bi.collection.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;

/**
 * 统计对象树结点定义
 * 
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @version $Revision$
 * 
 */
@Entity
@org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)
@Table(name="Rpt_StatisticalObjectTreeNodes")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class StatisticalObjectTreeNode implements Comparable<Object>, Serializable {
	
	private static final Log log = LogFactory.getLog(StatisticalObjectTreeNode.class);
	
	private static final long serialVersionUID = 8592411000910387496L;

	@Id
	@Column(name="SOTN_GUID",length=38)
	@GenericGenerator(name="StatisticalObjectTreeNode-assigned",strategy="assigned")
	private String guid;

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="SOT_GUID")
	private StatisticalObjectTree statisticalObjectTree;
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="CataLog_GUID",nullable=true)
	private Catalog catalog;
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="Parent_GUID",nullable=true)
	private StatisticalObjectTreeNode parentStatisticalObjectTreeNode;
	
	@OneToMany(cascade=CascadeType.REMOVE,fetch=FetchType.EAGER,mappedBy="parentStatisticalObjectTreeNode")
	@OrderBy("tabIndex")
	private List<StatisticalObjectTreeNode> children;
	
	@Column(name="Description",length=200)
	private String description;
	
	@Basic
	private Double tabIndex;
	
	/**
	 * 调查对象实例表中所对应父亲的字段名称
	 */
	@Column(name="parentColumnName",length=30)
	private String parentColumnName;
	
	/**
	 * 和调查对象实例表中对应父亲的字段，自己的字段的名称
	 */
	@Column(name="selfColumnName",length=30)
	private String selfColumnName;
	
	@Transient
	public String getSotGuid() {
		if (statisticalObjectTree != null) {
			return statisticalObjectTree.getGuid();
		}
		return "";
	}

	public void setSotGuid(String sotGuid) {
		if (sotGuid != null && sotGuid.trim().length() > 0) {
			if (statisticalObjectTree == null) {
				statisticalObjectTree = new StatisticalObjectTree();
			}
			statisticalObjectTree.setGuid(sotGuid);
		}
	}

	@Transient
	public String getTableName() {
		if (catalog != null) {
			return catalog.getTableName();
		}
		return "";
	}

	@Transient
	public String getSoGuid() {
		if (catalog != null) {
			return catalog.getGuid();
		}
		return "";
	}

	public void setSoGuid(String soGuid) {
		if (soGuid != null && soGuid.trim().length() > 0) {
			if (catalog == null) {
				catalog = new Catalog();
			}
			catalog.setGuid(soGuid);
		}
	}

	@Transient
	public String getParentGuid() {
		if (parentStatisticalObjectTreeNode != null) {
			return parentStatisticalObjectTreeNode.getGuid();
		}
		return "";
	}

	public void setParentGuid(String parentGuid) {
		if (parentGuid != null && parentGuid.trim().length() > 0) {
			if (parentStatisticalObjectTreeNode == null) {
				parentStatisticalObjectTreeNode = new StatisticalObjectTreeNode();
			}
			parentStatisticalObjectTreeNode.setGuid(parentGuid);
		}
	}

	@Transient
	private List offspring;

	/**
	 * 从catalog.name中获得
	 */
	@Transient
	@SuppressWarnings("unused")
	private String name;

	public String getParentColumnName() {
		return parentColumnName;
	}

	public void setParentColumnName(String parentColumnName) {
		this.parentColumnName = parentColumnName;
	}

	public String getSelfColumnName() {
		return selfColumnName;
	}

	public void setSelfColumnName(String selfColumnName) {
		this.selfColumnName = selfColumnName;
	}

	public List<StatisticalObjectTreeNode> getChildren() {
		return children;
	}

	public void setChildren(List<StatisticalObjectTreeNode> children) {
		this.children = children;
	}

	public List getOffspring() {
		if (offspring == null) {
			offspring = this.findAllOffspring();
		}
		return offspring;
	}
	
	private List<StatisticalObjectTreeNode> findAllOffspring(){
		List<StatisticalObjectTreeNode> allOffspring = new ArrayList<StatisticalObjectTreeNode>();
		
		allOffspring.addAll(this.getChildren());
		
		for(StatisticalObjectTreeNode node : this.getChildren()){
			allOffspring.addAll(node.findAllOffspring());
		}
				
		return allOffspring;
	}
	
	public Catalog getCatalog() {
		return catalog;
	}

	public void setCatalog(Catalog catalog) {
		this.catalog = catalog;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getGuid() {
		return guid;
	}

	public void setGuid(String guid) {
		this.guid = guid;
	}

	public StatisticalObjectTree getStatisticalObjectTree() {
		return statisticalObjectTree;
	}

	public void setStatisticalObjectTree(
			StatisticalObjectTree statisticalObjectTree) {
		this.statisticalObjectTree = statisticalObjectTree;
	}

	public StatisticalObjectTreeNode getParentStatisticalObjectTreeNode() {
		return parentStatisticalObjectTreeNode;
	}

	public void setParentStatisticalObjectTreeNode(
			StatisticalObjectTreeNode parentStatisticalObjectTreeNode) {
		this.parentStatisticalObjectTreeNode = parentStatisticalObjectTreeNode;
	}

	public Double getTabIndex() {
		return tabIndex;
	}

	public void setTabIndex(Double tabIndex) {
		this.tabIndex = tabIndex;
	}

	public String getName() {
		if (catalog == null)
			return "";
		return catalog.getName();
	}

	public void setName(String name) {
		if (catalog == null)
			catalog = new Catalog();
		catalog.setName(name);
	}

	/**
	 * @see java.lang.Comparable#compareTo(Object)
	 */
	public int compareTo(Object object) {
		StatisticalObjectTreeNode myClass = (StatisticalObjectTreeNode) object;
		return new CompareToBuilder()
			.append(this.tabIndex, myClass.tabIndex)
			.append(this.description,myClass.description)
			.append(this.guid, myClass.guid)
			.toComparison();
	}

	/**
	 * @see java.lang.Object#equals(Object)
	 */
	public boolean equals(Object object) {
		if (!(object instanceof StatisticalObjectTreeNode)) {
			return false;
		}
		StatisticalObjectTreeNode rhs = (StatisticalObjectTreeNode) object;
		return new EqualsBuilder().appendSuper(super.equals(object))
			.append(this.tabIndex, rhs.tabIndex)
			.append(this.description, rhs.description)
			.append(this.guid,rhs.guid)
			.isEquals();
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return new HashCodeBuilder(-1185466227, 989911599).appendSuper(
				super.hashCode())
				.append(this.tabIndex)
				.append(this.description)
				.append(this.guid)
				.toHashCode();
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return new ToStringBuilder(this)
			.append("tabindex", this.tabIndex)
			.append("description", this.description)
			.append("guid", this.guid)
			.toString();
	}
}